package org.tinycloud.tinyjob.utils.quartz;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.tinycloud.tinyjob.bean.entity.THostsInfo;
import org.tinycloud.tinyjob.bean.entity.THostsItem;
import org.tinycloud.tinyjob.client.constant.GlobalConstant;
import org.tinycloud.tinyjob.client.constant.HostItemHealthEnum;
import org.tinycloud.tinyjob.client.constant.HostTypeEnum;
import org.tinycloud.tinyjob.client.utils.MonitorUtils;
import org.tinycloud.tinyjob.mapper.HostsInfoMapper;
import org.tinycloud.tinyjob.mapper.HostsItemMapper;
import org.tinycloud.tinyjob.utils.SpringContextUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 内置服务节点健康状态监控定时任务
 * 根据节点心跳来进行判断，节点90秒内未更新则认为该节点已不健康
 * </p>
 *
 * @author liuxingyu01
 * @since 2025/8/22 20:49
 */
public class InternalMonitorJob implements Job {
    private static final Logger logger = LoggerFactory.getLogger(InternalMonitorJob.class);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        logger.info("InternalMonitorJob 执行定时任务: {}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        // 可以添加具体的监控逻辑，如检查系统状态、发送监控报告等
        HostsItemMapper hostsItemMapper = SpringContextUtils.getBean(HostsItemMapper.class);
        HostsInfoMapper hostsInfoMapper = SpringContextUtils.getBean(HostsInfoMapper.class);

        // 自动注册的通过服务节点主动刷新来被动监控
        List<THostsInfo> autoList = hostsInfoMapper.selectList(Wrappers.<THostsInfo>lambdaQuery().select(THostsInfo::getId).eq(THostsInfo::getDelFlag, GlobalConstant.NOT_DELETED).eq(THostsInfo::getHostType, HostTypeEnum.AUTO.getCode()));
        List<THostsInfo> manualList = hostsInfoMapper.selectList(Wrappers.<THostsInfo>lambdaQuery().select(THostsInfo::getId).eq(THostsInfo::getDelFlag, GlobalConstant.NOT_DELETED).eq(THostsInfo::getHostType, HostTypeEnum.MANUAL.getCode()));
        if (!CollectionUtils.isEmpty(autoList)) {
            List<Long> autoIdList = autoList.stream().map(THostsInfo::getId).collect(Collectors.toList());
            List<THostsItem> hostsItemList = hostsItemMapper.selectList(Wrappers.<THostsItem>lambdaQuery().eq(THostsItem::getDelFlag, GlobalConstant.NOT_DELETED).in(THostsItem::getHostId, autoIdList));
            for (THostsItem hostsItem : hostsItemList) {
                LambdaUpdateWrapper<THostsItem> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(THostsItem::getId, hostsItem.getId());
                if (isRefreshedWithin90Seconds(hostsItem.getRefreshedAt())) {
                    updateWrapper.set(THostsItem::getHealthy, HostItemHealthEnum.HEALTH.getCode());
                } else {
                    updateWrapper.set(THostsItem::getHealthy, HostItemHealthEnum.UNHEALTH.getCode());
                }
                hostsItemMapper.update(updateWrapper);
            }
        }
        // 手动注册的通过telnet命令来主动监控
        if (!CollectionUtils.isEmpty(manualList)) {
            List<Long> manualIdList = manualList.stream().map(THostsInfo::getId).collect(Collectors.toList());
            List<THostsItem> hostsItemList = hostsItemMapper.selectList(Wrappers.<THostsItem>lambdaQuery().eq(THostsItem::getDelFlag, GlobalConstant.NOT_DELETED).in(THostsItem::getHostId, manualIdList));

            for (THostsItem hostsItem : hostsItemList) {
                LambdaUpdateWrapper<THostsItem> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(THostsItem::getId, hostsItem.getId());
                if (MonitorUtils.testTelnet(hostsItem.getHost(), Integer.parseInt(hostsItem.getPort()))) {
                    updateWrapper.set(THostsItem::getHealthy, HostItemHealthEnum.HEALTH.getCode());
                } else {
                    updateWrapper.set(THostsItem::getHealthy, HostItemHealthEnum.UNHEALTH.getCode());
                }
                hostsItemMapper.update(updateWrapper);
            }
        }


    }


    /**
     * 判断refreshedAt距离当前时间是不是小于90秒
     *
     * @param refreshedAt 刷新时间
     * @return true表示在90秒内被更新过，false表示超过90秒没有被更新过
     */
    public static boolean isRefreshedWithin90Seconds(Date refreshedAt) {
        // 若refreshedAt为null（从未更新过），直接返回false
        if (refreshedAt == null) {
            return false;
        }
        // 获取当前时间的毫秒数
        long currentTimeMillis = System.currentTimeMillis();
        // 获取refreshedAt的毫秒数
        long refreshedTimeMillis = refreshedAt.getTime();
        // 计算时间差（毫秒）
        long timeDiff = currentTimeMillis - refreshedTimeMillis;
        // 90秒 = 90 * 1000 毫秒
        long threshold = 90 * 1000;
        // 时间差 <= 阈值 → 在90秒内被更新过
        return timeDiff <= threshold;
    }
}
